home *** CD-ROM | disk | FTP | other *** search
- ;
- ; Program to attatch a given interrupt vector to a specific address
- ; Version One, Steve Kemp '95
- ;
- ; Operation, either
- ;
- ; HOOK [/?]
- ; or
- ; HOOK intnumber segment:offset *** ALL NUMBERS IN HEX
- ;
- ; Basically this routine was cobbled together in an hour from the Intview
- ; program, as such it is not the best way to do things, and is subject to
- ; strange input requirements... eg HOOK 21 0000:0000 not 0:0, and
- ; and HOOK 0F 1234:1234 not HOOK F 1234:1234
-
- parser:
- mov SI,80h
- parse_loop:
- inc SI ; Get ready for next character
- mov Dl,[SI] ; Get character from command tail
- cmp Dl,'/' ; Switch??
- jz found_slash ; If so goto switch routine
- cmp Dl,0Dh ; End of tail??
- jnz parse_loop ; If not repeat
-
- cmp SI,81h ; Still at start of tail??
- jnz parameters_entered ; If not continue
-
- mov DX,info_message ; Else queue up error message
- call print_string ; Print it
- jmp return2DOS ; and return to DOS
-
- parameters_entered:
- call calculate_numbers ; Calculate numbers on command line
- call print_confirm ; Print out the question info.
-
- mov Ah,08h ; get a keypress
- int 21h ; Here
- or Al,32 ; Convert it to lowercase
- cmp Al,'y' ; Was it a 'Yes'
- jz hook_interrupt ; If so go ahead
- mov DX,fail_mess ; Get ready to print 'Aborted' message
- call print_string ; Do it,
- jmp return2DOS ; then eturn to DOS
-
- hook_interrupt:
- mov AX,0004 ; Multiply the int. number by four
- mov BX,[int_number]
- mul BX ; Now!
- mov SI,AX ; Point index to correct location in
- mov CX,[segment_buffer] ; table, get values to insert
- mov BX,[offset_buffer]
-
- cli ; Stop all ints.
- push DS ; Save the data segment
- sub AX,Ax ; AX=0000
- push AX
- pop DS ; DS=0000
-
- mov [DS:SI],BX ; Update the offset entry
- inc SI
- inc SI
- mov [DS:SI],CX ; And the segment
-
- pop DS ; Restore the segment
- sti ; Enable the maskable ints again.
- mov DX,finished_mess ; Tell user we did it
- call print_string
- jmp return2DOS
-
-
- found_slash:
- inc SI ; Point to next letter
- mov Dl,[SI] ; Get it into Dl
- cmp Dl,'?' ; ? ?? If so print info about program
- jz info
- push DX ; Otherwise invalid switch. Save it
- mov DX,invalid_switch ; Print invalid switch message
- call print_string ; Here
- pop DX ; Get back saved letter
- add Dl,'A'-'a' ; Print uppercase version of letter
- mov Ah,02 ; Print a single character
- int 21h ; Now!
- return2DOS:
- mov Ah,4ch ; Return to DOS
- int 21h ; There!
-
- info:
- mov DX,info_message ; Point to info. string
- call print_string ; Print the string
- jmp return2DOS ; finished!
-
- ;
- ; This routine calculates the parameters from the command line.
- ; They MUST be in the correct format. Code could be improved here a lot
- ; ... version two ...
- calculate_numbers:
- mov SI,82h ; Number is first parameter on Command
- mov DI,ascii_buffer ; Put a copy of it into the temporary
- movsw ; buffer
- movsw
-
- push SI ; Save position
- ; [Calculating the int number here]
- mov SI,ascii_buffer ; Point to int_number
- call hex_number ; Convert it to a number
- mov DX,[temp] ; Get it from the store
- mov [int_number],DX ; where it was placed, and put it in the
- ; interrupt number store
- ; [Calculating Segment now]
- pop SI ; Get back the pointer to the
- dec SI ; command line, point to the next byte
- push SI ; Save the pointer
- call hex_number ; Work out the high byte.
- mov dx,[temp] ; Get the result
- mov Dh,Dl ; Put the high byte in the right place
- mov [segment_buffer],dx ; Store it in the store
- pop SI ; Get back the pointer
- inc SI ; Point to the low-byte digits
- inc SI
- push SI ; Save pointer on the stack
- call hex_number ; Work out the low-byte
- mov dx,[temp] ; Get it from the store
- mov ax,[segment_buffer] ; Get the previously calculated hb
- mov dh,ah ; Form the word
- mov [segment_buffer],dx ; Finished, put the word in the store
-
- ; [Calculating the offset now]
- pop SI ; Get our pointer back
- inc SI ; Point past the low segment byte
- inc SI
- inc SI ; And the deliminator
- push SI ; Save pointer for later
- call hex_number ; Work out high byte
- mov dx,[temp] ; get the result
- mov Dh,Dl ; Put high byte in the right place
- mov [offset_buffer],dx ; which is the offset_buffer
- pop SI ; Get back the pointer
- inc SI ; increase to point to the low byte's
- inc SI ; digits
- call hex_number ; Calculate them.
- mov dx,[temp] ; Add up the high, and low bytes
- mov ax,[offset_buffer]
- mov dh,ah
- mov [offset_buffer],dx ; Stick result in the store..
-
- ret ; Finished calculating parameters
-
- ;
- ; Routine to turn a ascii value into a number. Result put in [Temp]
- ;
- hex_number:
- mov Dl,[SI] ; Get a character
- inc SI ; Move pointer up by one
- mov Dh,[SI] ; Get another character
- or Dh,32 ; Convert secont character to lower case
- cmp Dh,'h' ; Is it a 'h'
- jz one_digit_hex ; If so number is one ASCII-byte long
-
- two_digit_hex: ; Else it MUST be two ASCII-bytes long
- cmp Dl,'9'
- jle less_than_nine_1 ; Is it a number??
- or Dl,32 ; If not its a letter, lowercase it becomes
- sub dl,'a'-10-'0' ; Adjust value
- less_than_nine_1:
- sub Dl,'0' ; Convert it to number 0-15
- mov AX,16 ; Get ready to multiply by 16
- mov Dh,00
- mul DX ; Do it! (Result in AX)
- push AX ; Save result on stack
- mov Dl,[SI] ; Get next digit
- call one_digit_hex ; Treat it as a one digit number
- pop AX ; Restore the value that we saved
- add AX,DX ; Add high+low results
- mov [temp],AX ; Finally store the result in the bufffer
- ret ; Finished (Phew!)
-
- one_digit_hex:
- cmp Dl,'9' ; Is it a digit??
- jle less_than_nine_2 ; If so goto digit routine
- or dl,32 ; Convert letter to lower case
- sub Dl,'a'-'9'-1 ; Adjust it
- less_than_nine_2:
- sub Dl,'0' ; Convert it to a number 0-15
- mov Dh,00 ; Blank out high byte
- mov [temp],DX ; Store in the buffer
- ret ; Return
-
- ;
- ; This routine prints the contents of Ah as a two-byte hex number.
- ;
- print_hex:
- mov al,ah
- shr ah,1
- shr ah,1
- shr ah,1
- shr ah,1
- cmp ah,9
- jbe next1
- add ah,7
- next1:
- add ah,'0'
- and al,0fh
- cmp al,9
- jbe next2
- add al,7
- next2:
- add al,'0'
- push cx
- mov cl,ah
- mov ch,al
- mov Ah,02
- mov Dl,cl
- int 21h
- mov Ah,02
- mov Dl,ch
- int 21h
- pop cx
- ret
-
- print_confirm:
- mov DX,first_message ; Print first part of message
- call print_string ; now!
-
- mov ax,[int_number] ; print int number
- mov ah,al
- call print_hex ; Here
-
- mov DX,second_message ; print more message
- call print_string ; here
-
- print_segment: ; Print the segment
- mov DX,[segment_buffer] ; Get a copy of the segment address
- push DX ; Save it onto the stack
- mov Ah,Dh ; Get ready to print the high byte
- call print_hex ; Do it!
- pop DX ; Retore the value
- mov Ah,Dl ; Print the low byte
- call print_hex ; Here
-
- mov ah,2 ; Print a single character
- mov Dl,':' ; A seperator
- int 21h ; Now!
-
- print_offset:
- mov DX,[offset_buffer] ; Get a copy of the segment offset
- push DX ; Save it onto the stack
- mov Ah,Dh ; Get ready to print the high byte
- call print_hex ; Do it!
- pop DX ; Retore the value
- mov Ah,Dl ; Print the low byte
- call print_hex ; Here
-
- mov Ah,02 ; Print a single character
- mov Dl,'?' ; A question mark
- int 21h ; Now!
-
- ret ; Return
-
- print_string:
- mov Ah,09h ; Get ready to output the string addressed
- int 21h ; By DX. Do it.
- ret ; Return
-
- ; **************************************************************************
- ; * Output Strings and Data area *
- ; ********************************
-
- invalid_switch:
- db "Invalid switch - /","$"
- info_message:
- db "HOOK Version One - Steven Kemp 1995",0ah,0dh
- db " Usage",0ah,0dh
- db " HOOK [/?] - Gives this info.",0ah,0dh
- db " Or",0ah,0dh
- db " HOOK xx ssss:oooo - Hooks int. number xx (hex), to",,0ah,0dh
- db " segment ssss, offset oooo.",0ah,0dh
- db 0ah,0dh
- db " ALL NUMBERS MUST BE IN FULL HEX, e.g. HOOK 0F 1234:0001"
- db "$"
- first_message:
- db " REALLY hook the int ","$"
- second_message:
- db "h handler to ","$"
- fail_mess:
- db 0ah,0dh,"Hook operation cancelled at users request.","$"
- finished_mess:
- db 0ah,0dh,"Interrupt hooked.","$"
- ascii_buffer:
- db 00,00,00
- temp:
- dw 0000
- int_number:
- dw 0000h
- offset_buffer:
- dw 0000h
- segment_buffer:
- dw 0000h
-